<template>
  <div :class="[prefixCls+'-all']">
    <div :class="[prefixCls+'-frame']" v-if="searchForm">
      <div :class="[prefixCls+'-title']" v-if="config.title"><span>{{config.title}}</span></div>
      <div :class="[prefixCls+'-search']">
        <div :class="[prefixCls+'-simple-search']">
          <el-form :inline="true" :model="formParam" :class="prefixCls + '-form-inline'" ref="searchFormRef" label-width="100px">
            <el-form-item v-for="(item, index) in searchForm" :key="index" :label="item.label" :prop="item.key" :class="[prefixCls+'-search-item']" v-if="prefixCls !=='grid' || (prefixCls==='grid' && index < 3)">
              <el-input v-if="item.type === 'input'" v-model="formParam[item.key]"></el-input>
              <el-date-picker v-if="item.type === 'date'" v-model="formParam[item.key]" value-format="yyyy-MM-dd"></el-date-picker>
              <el-select v-if="item.type === 'select'" v-model="formParam[item.key]" style="width: 202px">
                <el-option v-for="(d,i) in tempDict[item.key]" :key="i" :label="d.label" :value="d.value"></el-option>
              </el-select>
              <el-select v-if="item.type === 'multipleSelect'" multiple v-model="formParam[item.key]">
                <el-option v-for="(d,i) in tempDict[item.key]" :key="i" :label="d.label" :value="d.value"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item  :class="[prefixCls+'-search-item']">
              <el-button type="danger" @click="search">查询</el-button>
              <el-button @click="resetForm()">重置</el-button>
              <el-button v-if="prefixCls==='grid' && searchForm.length > 3" @click="moreShow = !moreShow">更多</el-button>
              <slot name="form-action"></slot>
            </el-form-item>
            <div v-if="moreShow">
              <el-form-item v-for="(item, index) in searchForm" :key="index" :label="item.label" :prop="item.key" :class="[prefixCls+'-search-item']" v-if="prefixCls==='grid' && index >= 3">
                <el-input v-if="item.type === 'input'" v-model="formParam[item.key]"></el-input>
                <el-date-picker v-if="item.type === 'date'" v-model="formParam[item.key]" value-format="yyyy-MM-dd"></el-date-picker>
                <el-select v-if="item.type === 'select'" v-model="formParam[item.key]">
                  <el-option v-for="(d,i) in tempDict[item.key]" :key="i" :label="d.label" :value="d.value"></el-option>
                </el-select>
                <el-select v-if="item.type === 'multipleSelect'" multiple v-model="formParam[item.key]">
                  <el-option v-for="(d,i) in tempDict[item.key]" :key="i" :label="d.label" :value="d.value"></el-option>
                </el-select>
              </el-form-item>
            </div>
          </el-form>
        </div>
      </div>
    </div>
    <div :class="[prefixCls+'-frame']">
      <div :class="[prefixCls+'-title table-title']" v-if="config.title">
        <span>{{config.title}}列表</span>
        <div :class="[prefixCls+'-table-action']">
          <slot name="table-action"></slot>
        </div>
      </div>
      <slot name="table-tip"></slot>
      <div :class="[prefixCls+'-table']">
        <el-table :data="tableData" border style="width: 100%" :height="config.tableHeight" ref="commonTable" @selection-change="handleSelectionChange" @row-dblclick="dbClickAction" :header-cell-class-name="prefixCls+'-table-header-cell'" :cell-class-name="prefixCls+'-table-cell'">

          <el-table-column type="selection" align="center" width="50" v-if="config.crudMapping.delete || config.selection"></el-table-column>
          <el-table-column label="序号" align="center" width="60" v-if="config.isNo">
            <template slot-scope="scope">
              {{scope.$index + pageSize*(pageNo-1) + 1}}
            </template>
          </el-table-column>
          <el-table-column v-for="(item, index) in columns" v-if="!item.render && !item.hidden" :key="index" :prop="item.key" :label="item.label" :sortable="item.order?'custom':false" :width="item.width" :align="item.align">
          </el-table-column>
          <el-table-column :label="item.label" v-else-if="!item.hidden" :width="item.width" :sortable="item.order?'custom':false" :align="item.align">
            <template slot-scope="scope">
              <table-cell :row="scope.row" :render="item.render" :index="scope.$index"></table-cell>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div :class="[prefixCls+'-page']" v-if="config.isPage">
        <el-pagination :current-page="pageNo" :page-sizes="[10, 50, 100]" :page-size="pageSize"  layout="total, sizes, prev, pager, next, jumper" :total="total" @current-change="pageChange" @size-change="sizeChange">
        </el-pagination>
      </div>
    </div>
  </div>
</template>
<script>
  import TableCell from './table-cell'; //动态渲染用js
  export default {
    data() {
      return {
        tableData: [], //列表数据
        formParam:{}, //查询表单
        searchParam:{}, //查询用数据，与查询表单结构一样。由于翻页时，即使查询数据变更也不会用新的数据查询，这里深拷贝一份
        pageNo: 1, //页码
        pageSize: 10, //显示行数
        total: 0, //总数据条数
        multipleSelection: [], //当前选中行数据
        moreShow: false,
        tempOrder: '',
        prefixCls: 'grid',
        tempDict:{}
      }
    },
    props:['columns','searchForm','config','factoryIds'],
    watch:{
      factoryIds(){
        this.search();
      } 
    },
    methods:{
      searchInit(){ //查询表单初始化,将数组=>Object用于数据双向绑定
        this.searchForm.forEach((item)=>{
          this.$set(this.formParam, item.key, '');
          if (item.dict && item.dict instanceof Array) {
            this.$set(this.tempDict, item.key, item.dict)
          } else if (item.dict && item.dict.url) {

            let arrayParam = item.dict.url.match(new RegExp('(\\w+?)(?=})', 'g'));
            if (arrayParam && arrayParam.length > 0) {
              for (let i=0; i < arrayParam.length; i++) {
                let _this = this;
                this.$watch( 'formParam.' + arrayParam[i], function (val) {
                  let url = item.dict.url.replace('{' + arrayParam[i] + '}', val);
                  let method = item.dict.method? item.dict.method: 'post';
                  _this.formParam[item.key] = '';
                  _this.axios[method](url).then((res)=>{
                    let array = res.data.map((d)=>{
                      return {
                        label: d[item.dict.label],
                        value: d[item.dict.value]
                      }
                    });
                    _this.$set(this.tempDict, item.key, array);
                  });
                });
              }
            } else {
              let method = item.dict.method? item.dict.method: 'post';
              this.axios[method](item.dict.url).then((res)=>{
                let array = res.data.map((d)=>{
                  return {
                    label: d[item.dict.label],
                    value: d[item.dict.value]
                  }
                });
                this.$set(this.tempDict, item.key, array);
              });

            }
          }
        });
      },
      resetForm(){ //重置
        this.$refs['searchFormRef'].resetFields();
      },
      getTableData(){
        return this.tableData;
      },
      search(){ //查询
        //编辑查询用参数
        this.editParam(this.formParam);
        this.refreshTable();
      },
      refreshTable(){
        this.tableData = null;
        this.pageNo = 1;
        this.searchPost();
      },
      searchPost() { //查询请求
        let data = {};
        if (this.searchForm) {
          data = Object.assign({}, this.searchParam, {
            pageNo: this.config.isPage?this.pageNo:0,
            pageSize: this.config.isPage?this.pageSize:0
          });
        }
        if (this.config.crudMapping.query.data) {
          data = Object.assign({}, data, this.config.crudMapping.query.data);
          Object.keys(this.config.crudMapping.query.data).forEach(k=>{
            this.formParam[k]=this.config.crudMapping.query.data[k]+'';
          })
        }
        data.factIds=this.factoryIds;
        console.log(data);
        this.axios.post(this.config.crudMapping.query.url, data).then((response)=>{
          if (this.config.crudMapping.query.resultFun && typeof this.config.crudMapping.query.resultFun === 'function') {
            let result = this.config.crudMapping.query.resultFun(response);
            if (result && result.list)
              this.tableData = result.list;
            if (result && result.total)
              this.total = result.total;
          } else {              
            this.tableData = response.data.rows;
            this.total = response.data.total;
          }
        });
      },
      editParam(formParam){ //编辑查询用参数
        this.searchParam = {};
        for (let key in formParam) {
          if (typeof(formParam[key]) === 'string' && formParam[key].trim() !== '') {
            this.searchParam[key] = formParam[key];
          }
        }
      },
      pageChange(index){ //翻页
        this.pageNo = index;
        this.searchPost();
      },
      sizeChange(size){ //每页显示行数变更
        this.pageSize = size;
        this.refreshTable();
      },
      handleSelectionChange(array){
        this.multipleSelection = array;
      },
      dbClickAction(row, event){
        this.$emit('db-row-click', row);
      }
    },
    components: {
      TableCell
    },
    created(){
      if (this.config && this.config.prefixCls) {
        this.prefixCls = this.config.prefixCls;
      }
      if (this.searchForm && this.searchForm != null) {
        this.searchInit();
      }
      // this.search();
    }
  }
</script>
<style scoped>
  .grid-all{
    margin: 16px;
  }

  .grid-frame{
    padding: 16px;
    border: 1px solid #DCDFE6;
    margin-bottom: 16px;
  }

  .grid-frame .grid-title{
    font-size: 16px;
    font-weight: bold;
    color: #606266;
    padding-bottom: 16px;
    border-bottom: 1px solid #E4E7ED;
    box-sizing:border-box;
    -moz-box-sizing:border-box; /* Firefox */
    -webkit-box-sizing:border-box; /* Safari */
  }

  .grid-frame .grid-title span{
    width: 300px;
    display: inline-block;
    box-sizing:border-box;
    -moz-box-sizing:border-box; /* Firefox */
    -webkit-box-sizing:border-box; /* Safari */
  }

  .grid-frame .grid-title.table-title{
    border-bottom: none;
  }

  .grid-frame .grid-title.table-title .grid-table-action{
    width: calc(100% - 305px);
    display: inline-flex;
    justify-content: flex-end;
    box-sizing:border-box;
    -moz-box-sizing:border-box; /* Firefox */
    -webkit-box-sizing:border-box; /* Safari */
  }

.grid-table-tip{
    display: inline-flex;
    /* justify-content: flex-end; */
    box-sizing:border-box;
    -moz-box-sizing:border-box; /* Firefox */
    -webkit-box-sizing:border-box; /* Safari */
  }

  .grid-frame .grid-simple-search .grid-search-item{
    margin-top: 16px;
    margin-right: 16px;
  }

  .grid-frame .grid-page{
    margin-top: 16px;
  }

  .select-frame {
    margin-bottom: 8px;
  }

  .select-frame .select-page{
    margin-top: 8px;
  }

  /*.fade-enter-active, .fade-leave-active {*/
    /*transition: opacity .8s*/
  /*}*/
  /*.fade-enter, .fade-leave-to !* .fade-leave-active in below version 2.1.8 *! {*/
    /*opacity: 0;*/
  /*}*/
</style>
<style>
  .select-frame .select-table-header-cell{
    padding: 8px 0;
  }

  .select-frame .select-table-cell{
    padding: 8px 0;
  }
</style>
